<?php

namespace app\Services\api;

use app\commands\Idcard;
use yii;
use app\commands\LibUtil;
use app\models\Country;
use app\models\User;
use app\models\Ivtcode;
use app\models\PltfCard;
use app\models\UserAvter;
use app\models\UserLimit;
use app\models\VerificationCode;
use app\Services\ApiService;
use Carbon\Carbon;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Exception;
use Faker\Provider\UserAgent;
use yii\data\Pagination;

class UserService extends ApiService
{

    /**
     * @return Service_Pay
     */
    public static function getInstance()
    {
        return parent::getInstance();
    }


    /**
     * 登录
     */
    public function login($arr)
    {
        # 查询用户
        // $where = [
        //     'Username'  => $arr['username'],
        //     // 'Password'  => $arr['password']
        // ];
        $where = [];
        if (isset($arr['email']) && !empty($arr['email'])) {
            $where = [
                'email'  => $arr['email'],
            ];
        } elseif (isset($arr['cellphone']) && !empty($arr['cellphone'])) {
            $where = [
                'Cellphone'  => $arr['cellphone'],
            ];
        }

        $user = User::find()->where($where)->asArray()->one();
        if (empty($user)) {
            $user = User::find()->where(['Username'  => $arr['username']])->asArray()->one();
            if(empty($user)){
                // return ['code' => -1, 'message' => '用户名或者密码错误'];
                return ['code' => -1, 'message' => '用户不存在'];
            }
        }
        // Verification code验证       
        $validation = self::validationCode(trim($arr['username']), $arr['verification_code']);
        if ($validation !== true) {
            return ['code' => -1, 'message' => $validation];
        }
        // 邀请码信息验证
        if (isset($arr['invite_code']) && !empty($arr['invite_code'])) {
            // Invite code验证 
            $invite = self::inviteCode($arr['invite_code']);
            if (!is_array($invite)) {
                return ['code' => -1, 'message' => $invite];
            }
            $user_id = $user['ID'];
            if (!empty($invite['binging']) &&  $invite['binging']!=$user_id  ){
                return ['code' => -1, 'message' => "该邀请码已有绑定用户，不允许绑定"];
            }

            // 开启事物
            $transaction = Yii::$app->db->beginTransaction();
            try {
                // 修改用户Level
                Yii::$app->db->createCommand()->update(User::tableName(), ['Level' => $invite['level']], ['ID' => $user_id])->execute();
                // 判断用户是否已使用过邀请码
                $ivtcode = Ivtcode::find()->where(['binging' => $user_id])
                    ->select(['ID', 'binging', 'used'])->asArray()->all();
                if (!empty($ivtcode)) {
                    foreach ($ivtcode as $key => $time) {
                        // 还原历史使用邀请码状态
                        Yii::$app->db->createCommand()->update(Ivtcode::tableName(), ['binging' => 0, 'used' => 0], ['ID' => $time['ID']])->execute();
                    }
                }
                // 修改邀请码状态
                Yii::$app->db->createCommand()->update(Ivtcode::tableName(), ['binging' => $user_id, 'used' => 1], ['ID' => $invite['ID']])->execute();
                $transaction->commit();
            } catch (Exception $e) {
                $transaction->rollBack();
                return ['code' => -1, 'message' => $e->getMessage()];
            }
        }
        // if (!empty($arr['ivtcode'])) {
        //     $where = [
        //         'code' => $arr['ivtcode']
        //     ];

        //     $ivt_code = Ivtcode::find()
        //         ->where($where)
        //         ->asArray()
        //         ->one();
        //     if (empty($ivt_code)) {
        //         return ['code' => -1, 'message' => '邀请码不存在'];
        //     }
        //     if (!empty($ivt_code['used'])) {
        //         return ['code' => -1, 'message' => '邀请码已使用'];
        //     }
        //     # 绑定用户
        //     $res = Yii::$app->db->createCommand()->update('`pltf.ivtcode`', ['binging' => $user['ID'], 'used' => 1], ['code' => $arr['ivtcode']])->execute();

        //     #修改用户类型
        //     $res = Yii::$app->db->createCommand()->update('`user.user`', ['level' => $ivt_code['level']], ['username' => $user['Username']])->execute();
        // }

        #生成token
        $token = $this->createToken($user);
        return ['code' => 200, 'message' => '登陆成功', 'data' => ['token' => $token]];
    }

    public function register($data)
    {
        // if (!preg_match("/^[a-zA-Z0-9\x{4e00}-\x{9fa5}]{2,20}$/u", $data['nickname'])) {
        //     return ['code' => -1, 'message' => 'nickname_format'];
        // }
        // if (!preg_match("/^[\x{4e00}-\x{9fa5}]{1,20}$/u", $data['name'])) {
        //     return ['code' => -1, 'message' => 'realname_format'];
        // }
        if (isset($data['cellphone']) && !empty($data['cellphone'])) {
            if (!preg_match("/^1[345789]\d{9}$/", $data['cellphone'])) {
                return ['code' => -1, 'message' => 'cellphone_forma'];
            }
            $is_exists_cellphone =  User::find()->where(['Cellphone' => $data['cellphone']])->asArray()->exists();
            if ($is_exists_cellphone) {
                return ['code' => -1, 'message' => 'cellphone_exist'];
            }
        }
        if (isset($data['email']) && !empty($data['email'])) {
            $is_exists_email =  User::find()->where(['email' => $data['email']])->asArray()->exists();
            if ($is_exists_email) {
                return ['code' => -1, 'message' => 'email_exist'];
            }
        }
        if (isset($data['id_card']) && !empty($data['id_card'])) {
            $idCard = new Idcard();
            $card =  $idCard->isChinaIDCard($data['id_card']);
            if (!$card) {
                return ['code' => -1, 'message' => 'idcard_format'];
            }
            $is_exists_id_card =  User::find()->where(['IDcard' => $data['id_card']])->asArray()->exists();
            if ($is_exists_id_card) {
                return ['code' => -1, 'message' => 'id_card_exist'];
            }
        }
        // 验证信息
        $is_exists_username = User::find()->where(['Username' => $data['username']])->asArray()->exists();
        if ($is_exists_username) {
            return ['code' => -1, 'message' => 'username_exist'];
        }
        // $is_exists_nickname =  User::find()->where(['Nickname' => $data['nickname']])->asArray()->exists();
        // if ($is_exists_nickname) {
        //     return ['code' => -1, 'message' => 'nickname_exist'];
        // }


        // Verification code验证       
        $validation = self::validationCode(trim($data['username']), $data['verification_code']);
        if ($validation !== true) {
            return ['code' => -1, 'message' => $validation];
        }
        $default_level = 1; // 默认 $default_leavel
//        if (isset($data['invite_code']) && !empty($data['invite_code'])) {
//            // Invite code验证
//            $invite = self::inviteCode($data['invite_code']);
//            if (!is_array($invite)) {
//                return ['code' => -1, 'message' => $invite];
//            }
//
//            if (!empty($invite['binging']) ){
//                return ['code' => -1, 'message' => "该邀请码已有绑定用户，不允许绑定"];
//            }
//            $default_level = $invite['level'];
//        }
        if (is_numeric($data['username'])) {
            if (!preg_match("/^1[345789]\d{9}$/", $data['username'])) {
                return ['code' => -1, 'msg' => '手机号格式不合法'];
            }
        }
        $info = [
            'Username' => trim($data['username']),
            // 'Password' => $data['password'] ?? NULL,
            'Nickname' => trim($data['nickname']) ?? NULL,
            'EnglishName' => trim($data['english_name']) ?? NULL,
            'EnglishCompany' => trim($data['english_company']) ?? NULL,
            'EnglishPosition' => trim($data['english_position']) ?? NULL,
            'Company' => $data['company'] ?? NULL,
            'Position' => $data['position'] ?? NULL,
            'Cellphone' => $data['cellphone'] ?? NULL,
            'Name' => (isset($data['name']) && !empty($data['name'])) ? trim($data['name']) : NULL,
            'IDcard' => $data['id_card'] ?? NULL,
            // 'CountryID' => (int) $data['country_id'] ?? NULL,
            'Activity' => $data['activity'] ?? 1,
            'Regist' => $data['regist'] ?? date('Y-m-d H:i:s', time()),
            'Level' => $data['level'] ?? $default_level,
            'updatetime' => date('Y-m-d H:i:s', time()),
            'email' => (isset($data['email']) && !empty($data['email'])) ? trim($data['email']) : NULL,
        ];
        // 开启事物
        $transaction = Yii::$app->db->beginTransaction();
        try {
            $sql = Yii::$app->db->createCommand();
            $sql->insert('`user.user`', $info)->execute();
            $user_id = Yii::$app->db->getLastInsertID();
            $mod_id = $data['modid'] ?? 1;
            $style = $data['style'] ?? 1;
            $activity = $data['activity'] ?? 1;
            $sql->insert(UserAvter::tableName(), ['userID' => $user_id, 'modID' => (int) $mod_id])->execute();
            $sql->insert(UserLimit::tableName(), ['userID' => $user_id, 'message' => (int) $data['message'], 'card' => (int) $data['card']])->execute();
            $sql->insert(PltfCard::tableName(), ['userID' => $user_id, 'style' => (int) $style, 'Activity' => (int) $activity])->execute();
            // 编辑邀请码绑定信息
            // if (isset($invite) && !empty($invite)) {
            //     $sql->update(Ivtcode::tableName(),
            //         ['binging' => $user_id, 'used' => 1],
            //         ['ID' => $invite['ID']])->execute();
            // }
            // 修改验证码文件中的userID
            $sql->db->createCommand()->update(
                VerificationCode::tableName(),
                ['userID' => $user_id],
                ['send_to' => trim($data['username']), 'code' => $data['verification_code']]
            )->execute();
            $transaction->commit();
            // 获取User信息
            $user = User::find()->where(['ID' => $user_id])->asArray()->one();
            $token = $this->createToken($user);
            return ['code' => 200, 'message' => '注册成功', 'data' => ['token' => $token]];
        } catch (Exception $e) {
            $transaction->rollBack();
            return ['code' => -1, 'message' => "注册失败，请稍后重试"];
        }
    }

    /**
     * 获取国籍列表
     */
    public function getUserCountry()
    {
        $country =  Country::find()->where(['level' => '2'])->select(['id', 'name', 'name_en'])->asArray()->all();
        if (!empty($country)) {
            return ['code' => 200, 'country' => $country];
        }
    }

    /**
     * 用户生成token
     */
    public function createToken($user)
    {
        $signer = new Sha256(); //使用Sha256加密，常用加密方式有Sha256,Sha384,Sha512
        $time = time();
        $tokenBuilder = (new Builder())
            ->issuedBy(Yii::$app->params['host']) // 设置发行人
            ->permittedFor(isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '') // 设置接收
            ->identifiedBy(Yii::$app->security->generateRandomString(10), true) // 设置id
            ->issuedAt($time) // 设置生成token的时间
            ->canOnlyBeUsedAfter($time+12*60)   // 设置token使用时间(实时使用)
            ->expiresAt($time + 60*60*12);      //设置token过期时间

        unset($user['password']);
        $tokenBuilder->withClaim('user', $user);
        $tokenBuilder->withClaim('login', '登录');
        //使用Sha256加密生成token对象，该对象的字符串形式为一个JWT字符串
        $token = $tokenBuilder->getToken($signer, new Key('jwt_secret'));
        return (string) $token;
    }

    /**
     * 用户列表 (默认普通用户)
     */
    public function getUserList($req)
    {
        $limit = !empty($req['num']) ? $req['num'] : 2;
        $offset = !empty($req['page']) ? ($req['page'] - 1) * $limit : 0;
        $where = ['Level' => 1];
        if (!empty($req['Level'])) {
            $where['Level'] = $req['Level'];
        }
        $model = User::find()
            ->select('ID,Username,IDcard,Cellphone,Company,Position,Activity')
            ->where($where);
        $totalCount  = $model->count();
        if (!$totalCount) {
            return ['code' => -1, 'message' => '暂无数据'];
        }
        $pages = new Pagination(['totalCount' => $model->count()]);
        $list = $model->offset($offset)
            ->limit($limit)
            ->asArray()
            ->all();
        if (empty($list)) {
            return ['code' => -1, 'message' => '暂无数据'];
        }
        return ['code' => 200, 'data' => ['list' => $list, 'totalCount' => $totalCount]];
    }


    /**
     * 用户详情
     */
    public function getUserInfo($userID)
    {
        $info = User::find()
            ->select('ID, Username, Nickname,  Company,  Position,  Cellphone,  Name,  IDcard,  CountryID,  Activity,  Regist,  Level')
            ->where(['ID' => $userID])
            ->asArray()
            ->one();
        if (empty($info)) {
            return ['code' => -1, 'message' => '暂无数据'];
        }
        return ['code' => 200, 'data' => $info];
    }


    /**
     * 保存用户信息
     */
    public function saveUserInfo($req)
    {
        $time = date("Y-m-d H:i:s", time());
        $info = [
            'Username' => $req['Username'],
            'Password' => $req['Password'],
            'Name'     => $req['Name'],
            'Nickname' => !empty($req['Nickname']) ? $req['Nickname'] : null,
            'Company'  => !empty($req['Company']) ? $req['Company'] : null,
            'Position' => !empty($req['Position']) ? $req['Position'] : null,
            'Cellphone' => !empty($req['Cellphone']) ? $req['Cellphone'] : null,
            'IDcard'   => !empty($req['IDcard']) ? $req['IDcard'] : null,
            'Activity' => !empty($req['Activity']) ? $req['Activity'] : 1,
            'Level'    => !empty($req['Level']) ? $req['Level'] : 1,
            'updatetime' => $time,
        ];
        if (!empty($req['userID'])) {
            $count = User::find()
                ->where(['ID' => $req['userID']])
                ->count();
            if (!$count) {
                return ['code' => -1, 'message' => '没有该用户'];
            }
            # update
            $res = Yii::$app->db->createCommand()->update('`user.user`', $info, ['ID' => $req['userID']])->execute();
        } else {
            $info['Regist'] = $time;
            $res = Yii::$app->db->createCommand()->insert('`user.user`', $info)->execute();
        }
        if ($res) {
            return ['code' => 200, 'message' => '保存成功'];
        }
        return ['code' => -1, 'message' => '保存失败，请稍后重试'];
    }


    /**
     *  解封/封禁用户
     *
     */
    public function activeUser($req)
    {
        $info = User::find()
            ->where(['ID' => $req['userID']])
            ->count();
        if (empty($info)) {
            return ['code' => -1, 'message' => '没有该用户'];
        }
        $update = [
            'updatetime' => date("Y-m-d H:i:s", time()),
            'Activity'   => intval($req['Activity'])
        ];
        $res = Yii::$app->db->createCommand()->update('`user.user`', $update, ['ID' => intval($req['userID'])])->execute();
        if ($res) {
            return ['code' => 200, 'message' => '操作成功'];
        }
        return ['code' => -1, 'message' => '操作失败，请稍后重试'];
    }

    /**
     * 验证码code验证
     *
     * @param [type] $username
     * @param [type] $code
     * @return void
     */
    public static function validationCode($username, $code)
    {
        // 获取验证码最后一条信息
        $info =  VerificationCode::find()->where(['send_to' => $username, 'code' => $code])
            ->select(['ID','code', 'createtime', 'validtime', 'verificationtime'])
            ->asArray()
            ->one();
           
        if (!empty($info)) {
            // 判断是否已过有效期
            $min = (time() - strtotime($info['createtime'])) / 60;
            if ($min  >= $info['validtime']) {
                return '验证码已过期';
            }
            // 添加效验时间
            try{
                $verificationtime = date('Y-m-d H:i:s', time());
                Yii::$app->db->createCommand()->update(VerificationCode::tableName(), ['verificationtime' => $verificationtime], ['ID' => $info['ID']])->execute();
            }catch(Exception $e){
                return $e->getMessage();
            }
            return true;
        }
        return '不存在验证码信息';
    }

    /**
     * 邀请码code验证
     *
     * @param [type] $username
     * @param [type] $code
     * @return void
     */
    public static function inviteCode($code)
    {
        // 获取验证码最后一条信息
        $info = Ivtcode::find()->where(['code' => trim($code)])->andWhere(['isDelete' => 0])
            ->select(['ID', 'code', 'roomID', 'expire', 'binging', 'used', 'level', 'isDelete'])->asArray()->one();;
        if (!empty($info) && $info['code'] == $code) {
            // 判断是否已过有效期
            if (time() > strtotime($info['expire'])) {
                return '邀请码已过期';
            }
            if ($info['used'] == 1) {
                return '邀请码已被使用';
            }
            return $info;
        }
        return '不存在邀请码信息';
    }


    /**
     * 绑定邀请码
     */
    public function bindCode($invite_code,$user){
        // Invite code验证
        $invite = self::inviteCode($invite_code);
        if (!is_array($invite)) {
            return ['code' => -1, 'message' => $invite];
        }
        $user_id = $user->ID;
        if (!empty($invite['binging']) &&  $invite['binging']!=$user_id  ){
            return ['code' => -1, 'message' => "该邀请码已有绑定用户，不允许绑定"];
        }

        // 开启事物
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 修改用户Level
            Yii::$app->db->createCommand()->update(User::tableName(), ['Level' => $invite['level']], ['ID' => $user_id])->execute();
            // 判断用户是否已使用过邀请码
            $ivtcode = Ivtcode::find()
                ->where(['binging' => $user_id,'isDelete' => 0])
                ->select(['ID', 'binging', 'used'])->asArray()->all();

            if (!empty($ivtcode)) {
                foreach ($ivtcode as $key => $time) {
                    // 还原历史使用邀请码状态
                    Yii::$app->db->createCommand()->update(Ivtcode::tableName(), ['binging' => 0, 'used' => 0], ['ID' => $time['ID']])->execute();
                }
            }
            // 修改邀请码状态
            Yii::$app->db->createCommand()->update(Ivtcode::tableName(), ['binging' => $user_id, 'used' => 1], ['ID' => $invite['ID']])->execute();
            $transaction->commit();
            return ['code' => 200, 'message' => "绑定成功"];
        } catch (Exception $e) {
            $transaction->rollBack();
            return ['code' => -1, 'message' => "绑定失败，请稍后重试"];
        }
    }


}
